//
//  NSString+Lc.m
//  18Birdies
//
//  Created by Lc on 15/3/20.
//  Copyright (c) 2015年 Lc. All rights reserved.
//

#import "LcFont.h"
#import "NSString+Lc.h"
#import "LcPreconditions.h"

@implementation NSString (Lc)

- (BOOL)isValidPhoneNumber {
  NSString* regex = @"[1-9][\\d]{7,14}";
  if (self.trim.length == 0) {
    return NO;
  }
  NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
  return [predicate evaluateWithObject:self.trim];
}

- (BOOL)contains:(NSString*)string {
  NSRange range = [self rangeOfString:string];
  return range.length > 0;
}

- (BOOL)containsIgnoreCase:(NSString*)string {
  NSRange range = [self rangeOfString:string options:NSCaseInsensitiveSearch];
  return range.length > 0;
}

+ (NSString*)stringWithData:(NSData*)data {
  return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

- (NSData*)toData {
  return [self dataUsingEncoding:NSUTF8StringEncoding];
}

+ (NSString*)stringForKey:(NSString*)key table:(NSString*)table {
  return [[NSBundle mainBundle] localizedStringForKey:key value:nil table:table];
}

- (float)widthWithLcFont:(LcFont*)lcFont {
  CGRect rect = [self boundingRectWithSize:CGSizeMake(MAXFLOAT, 1)
                                   options:kNilOptions
                                attributes:@{
                                  NSFontAttributeName : lcFont.font
                                }
                                   context:nil];
  CGFloat width = rect.size.width + 1;
  return width;
}

- (float)heightOfFont:(UIFont*)font andWidth:(float)width {
  return [self sizeOfFont:font andWidth:width].height;
}

- (CGSize)sizeOfFont:(UIFont*)font andWidth:(float)width {
  NSDictionary* attribute = @{NSFontAttributeName : font};

  CGSize retSize = [self boundingRectWithSize:CGSizeMake(width, 9999999)
                                      options:NSStringDrawingTruncatesLastVisibleLine |
                                              NSStringDrawingUsesLineFragmentOrigin |
                                              NSStringDrawingUsesFontLeading
                                   attributes:attribute
                                      context:nil]
                       .size;

  return retSize;
}

- (NSString*)trim {
  return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString*)remove:(NSString*)subString {
  if ([self containsString:subString]) {
    NSString* removedString = [self stringByReplacingOccurrencesOfString:subString withString:@""];
    return removedString;
  }
  return self;
}

- (NSString*)numberString {
  NSMutableString* numberString = [[NSMutableString alloc] init];
  for (int i = 0; i < self.length; ++i) {
    unichar character = [self characterAtIndex:i];
    if (character >= '0' && character <= '9') {
      [numberString appendString:[NSString stringWithFormat:@"%c", character]];
    }
  }
  return numberString;
}

- (BOOL)isStartWithLetter {
  if (self.length > 0) {
    unichar character = [self characterAtIndex:0];
    if ((character >= 'A' && character <= 'Z') || (character <= 'z' && character >= 'a')) {
      return YES;
    }
  }
  return NO;
}

- (NSString*)shortDisplayNameFormat {
  NSArray* array = [self.trim componentsSeparatedByString:@" "];
  if (array.count > 1) {
    NSString* firstName = [array firstObject];
    NSString* lastName = [array lastObject];
    if (firstName.length > 0 && lastName.length > 0) {
      NSString* firstCharacter = [firstName substringWithRange:NSMakeRange(0, 1)];
      return [NSString stringWithFormat:@"%@. %@", firstCharacter.uppercaseString, lastName];
    }
  }
  return self;
}

- (NSString*)uppercaseFirstCharacter {
  if (self.length == 0) {
    return self;
  }
  unichar firstCharacter = [self characterAtIndex:0];
  if (firstCharacter >= 'a' && firstCharacter <= 'z') {
    firstCharacter = firstCharacter + 'A' - 'a';
    return [self stringByReplacingCharactersInRange:NSMakeRange(0, 1)
                                         withString:[NSString stringWithCharacters:&firstCharacter
                                                                            length:1]];
  } else {
    return self;
  }
}

- (NSString*)lowercaseFirstCharacter {
  if (self.length == 0) {
    return self;
  }
  unichar firstCharacter = [self characterAtIndex:0];
  if (firstCharacter >= 'A' && firstCharacter <= 'Z') {
    firstCharacter = firstCharacter - ('A' - 'a');
    return [self stringByReplacingCharactersInRange:NSMakeRange(0, 1)
                                         withString:[NSString stringWithCharacters:&firstCharacter
                                                                            length:1]];
  } else {
    return self;
  }
}

- (NSString*)formatEllipsisWithLengthLimit:(int)lengthLimit {
  if (self.length <= lengthLimit) {
    return self;
  }
  lengthLimit = lengthLimit - 3; //@"..."
  NSString* tempString = [self substringToIndex:lengthLimit].trim;
  tempString = [NSString
      stringWithFormat:@"%@...",
                       [tempString substringToIndex:NSMaxRange([tempString
                                                        rangeOfComposedCharacterSequenceAtIndex:
                                                            tempString.length - 1])]];

  return tempString;
}

- (NSString*)formatEllipsisWithWidthLimit:(float)widthLimit lcFont:(LcFont*)lcFont {
  if ([self widthWithLcFont:lcFont] <= widthLimit) {
    return self;
  }
  int ellipsisWidth = [@"..." widthWithLcFont:lcFont] + 2;
  widthLimit = widthLimit - ellipsisWidth;
  NSString* tempString = self;
  NSUInteger length = self.length;
  for (NSUInteger i = length; i > 0; i--) {
    if ([tempString widthWithLcFont:lcFont] > widthLimit) {
      tempString = [tempString substringToIndex:tempString.length - 1];
    } else if (i != length) {
      tempString = tempString.trim;
      tempString = [NSString
          stringWithFormat:@"%@...",
                           [tempString substringToIndex:NSMaxRange([tempString
                                                            rangeOfComposedCharacterSequenceAtIndex:
                                                                tempString.length - 1])]];
      break;
    } else {
      break;
    }
  }
  return tempString;
}

- (NSString*)appendNextLineString:(NSString*)string {
  if (self.length == 0) {
    return string;
  }
  if (string.length == 0) {
    return self;
  }
  return [self stringByAppendingFormat:@"\n%@", string];
}

- (NSString*)appendNextLineStrings:(NSArray<NSString*>*)strings {
  NSString* string = self;
  for (NSString* subString in strings) {
    string = [string appendNextLineString:subString];
  }
  return string;
}

+ (NSString*)stringFromInt:(NSInteger)integer {
  return [NSString stringWithFormat:@"%ld", (long)integer];
}

+ (NSString*)stringFromLongLong:(long long)longValue {
  return [NSString stringWithFormat:@"%lld", longValue];
}

+ (instancetype)randomStringWithLength:(int)length type:(RandomStringType)type {
  LC_CHECK_TRUE(length >= 0 && length <= 1024);
  NSMutableString* string = [NSMutableString string];
  for (int i = 0; i < length; i++) {
    char c = 0;
    switch (type) {
      case RandomStringTypeLetters:
        c = (arc4random_uniform(2) == 0 ? 'a' : 'A') + arc4random_uniform(26);
        break;
      case RandomStringTypeNumbers:
        c = '0' + arc4random_uniform(10);
        break;
      case RandomStringTypeNumbersAndLetters: {
        int rand = arc4random_uniform(10 + 26 + 26);
        if (rand < 10) {
          c = '0' + rand;
        } else if (rand < 36) {
          c = 'a' + rand - 10;
        } else {
          c = 'A' + rand - 36;
        }
      } break;
      case RandomStringTypeNormalCharacter:
        c = ' ' + arc4random_uniform(95);
        break;
      case RandomStringTypeAllAsc2:
        c = arc4random_uniform(127);
        break;
      default:
        break;
    }
    if (c != 0) {
      [string appendFormat:@"%c", c];
    }
  }
  return string;
}

- (NSString*)subToIndex:(NSInteger)index {
  NSString* result = self;
  if (result.length > index) {
    NSRange rangeIndex = [result rangeOfComposedCharacterSequenceAtIndex:index];
    result = [result substringToIndex:(rangeIndex.location)];
  }
  return result;
}

- (NSString*)urlEncode {
  NSString* newString = [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]];
  if(newString){
    return newString;
  }
  return self;
}

- (NSString*)urlQueryParamEncode {
  NSMutableCharacterSet *charSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
  [charSet removeCharactersInString:@"!*'\"();:@&=+$,/?%#[] "];
  return [self stringByAddingPercentEncodingWithAllowedCharacters:charSet];
}

- (NSURL*)toFullUrl {
  LC_CHECK_TRUE(self.length > 0);
  NSURL* requestUrl = [NSURL URLWithString:self];
  if (requestUrl.scheme.length == 0) {
    requestUrl = [NSURL URLWithString:[@"https://" stringByAppendingString:self]];
  }
  return requestUrl;
}

@end
